import java.io.*;
import java.util.*; // ArrayList, TreeSet
import org.apache.commons.lang3.StringUtils;

public class StudentList {

	private static String STUDENT_FILE_HEADER = "# format: " +
	                                            "loginName" +
	                                            "[,courseID]*\n";
	
	/** 
	* Reads and parses a text file, containing a list of students and their courses, 
	* and builds an ArrayList of Student objects. Each student in the text file has 
	* zero or more courseIDs, which are matched to Course objects in the courseList.  
	* If a matching courseID is not found in the courseList, it is ignored and not
	* added to the Student object.   
	*
	* @param	studentFile		filename of text file to read
	* @param	courseList		ArrayList of Course objects
	* @return	ArrayList of Student objects
	*/
	public static ArrayList<Student> readStudentList(String studentFile,
		TreeSet<Course> courseList) {

		ArrayList<Student> studentList = new ArrayList<Student>();
		
		try {
			FileReader reader = new FileReader(new File(studentFile));
			BufferedReader buffer = new BufferedReader(reader);
			String line = null;

			// Read each line from StudentList.txt, and create a new Student
			// for each line.  Create an ArrayList of students.

			// skip the first line, which identifies the fields
			buffer.readLine();
			while ((line = (buffer.readLine())) != null) {
				Student newStudent = createStudent(line, courseList);
				studentList.add(newStudent);
			}
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		
		return studentList;	
	}    

	/** 
	* Adds a Student to the input ArrayList
	*
	* @param	aStudent		student to be added
	* @param	studentList		ArrayList to which the student will be added
	*/
	public static void addStudent(Student aStudent,
		ArrayList<Student> studentList) {
		studentList.add(aStudent);

	}    

	/** 
	* Finds and returns a Student, in the input ArrayList, with the specified login name.
	* If no match is found, the returned object reference is null.  
	*
	* @param	login			login name to find
	* @param	studentList		ArrayList of Student objects to be searched
	* @return	Student object with the specified login name, or null if not found
	*/
	public static Student getStudent(String login, ArrayList<Student> studentList) {
		// Find the student with the specified login name in the studentList.
		Student foundStudent = null;
		for (Student s : studentList) {
			if (s.getLogin().equals(login)) {
				foundStudent = s;
				break;
			}
		}
		return foundStudent;
	}
	
	/** 
	* Writes a text file, containing a list of students and their courses, 
	* using data from an ArrayList of Student objects.  If there is an existing text
	* file with the same name, it will be overwritten.
	*
	* @param	studentFile		filename of text file to write
	* @param	students		ArrayList of Student objects to be written out
	*/
	public static void writeStudentList(ArrayList<Student> students, String studentFile) {

		try {
			// Create a file containing all of the students, as updated.
			BufferedWriter writer = new BufferedWriter(new FileWriter(studentFile));
			
			// Write the first line, which documents the fields
			writer.write(STUDENT_FILE_HEADER);
			
			for (Student s : students)
			{
				writer.write(studentOutput(s) + "\n");
			}
			writer.close();
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		
		return;		
	}

    private static Student createStudent(String line, TreeSet<Course> courseList) {
		// Parse the input line into tokens, and use them to create a student.
		// Each line in StudentList.txt contains: 
		// loginName,courseList
		String[] tokens = line.split(",");

		// First, create the Student object with just the login name.
		Student nextStudent = new Student(
			tokens[0]); // loginName
		
		// Next, create an ArrayList from the remaining tokens, which contain courseIDs.
		// Start with token[1].
		ArrayList<String> courses = new ArrayList<String>();
		int numCourses = tokens.length;
		for (int n = 1; n < numCourses; n++) { 
			courses.add(tokens[n]);
		}
		
		// Now use the ArrayList of courseIDs to add the appropriate set of
		// courses to the student.
		nextStudent.addCourses(courses, courseList);
		
		return nextStudent;
    }
    
    private static String studentOutput(Student s) {
		// Create a comma-delimited string holding this student's info.
		// Each line in StudentList.txt contains: 
		// loginName,courseList
		// ... but if the student has no courses, the line will contain only loginName

		StringBuilder output = new StringBuilder(s.getLogin());
		String courses = new String(s.getCourseIDs());
		if (courses.length() > 0) {
			output.append("," + courses);
		}
		
    	return output.toString();
    }
}
